#include <input_kbdev.hpp>
#include <inputmanager.hpp>
#include <inputdrv_manage.hpp>
#include <iostream>
#include <boost/thread.hpp>
#include <utils/mime_common.hpp>
#include <boost/bind.hpp>
#include <utils/event_waiter_frame/event_waiter_frame.hpp>
#include <cstring>
#include <inputdev_func.hpp>
#include <elog.h>

using namespace std;

// UTF-8

static boost::mutex            mutex_singleton; 


static boost::mutex            local_mutex; 

static struct input_dev_param    *up_keycode_status_param;
static c_indevval                devval;

/****   设备在四种工作模式下，提供IPC保护机制的资源   *******/
static devfunc_notify  enroll_notify;
static devfunc_notify  auth_notify;

        // 删除用户接口的底层实现 应该做成 复用获取用户ID的接口。
        // 获取用户ID提供了更为广泛的方法。 而删除用户应该是对获取用户ID接口的使用。
static devfunc_notify  delete_the_user_notify;
static devfunc_notify  get_userid_notify;



/********  按键设备信息对象  **********/
static input_kbdev_info         o_dev_status;

static input_kbdev_enroll_paras o_kbdev_enroll;
static input_kbdev_auth_paras   o_kbdev_auth;



/**********注册、验证、获取ID等功能内部抽象的do-cancel这一逻辑对象****************/
event_waiter eventer_enroll_with_cacel(s_start_init);
event_waiter eventer_auth_with_cacel(s_start_init);  
event_waiter eventer_get_userid_with_cacel(s_start_init); 
/*** 
 event_waiter的设计上还需要新增一个参数，存入p_realtime_para_partdown,
 即存入 之前发起事件上半部时的传入参数。
 例如，注册的时候，会传入参数，取消注册的时候，也该使用此参数，填上外部实时传入的取消原因,以反馈给注册者

 暂时不来改了，这里直接使用一个全局变量先完成功能。
***/
static input_dev_param* p_para_func_enroll_part2;
static input_dev_param* p_para_func_auth_part2;


static void keys_report_handler(unsigned char keycode, unsigned char keyvalue, unsigned char execption_info) {

    log_d("keys_report_handler \n");

    devval.type = EV_KEY;
    devval.code = keycode;
    devval.value = keyvalue;
    devval.execption_info = execption_info;
 
    boost::unique_lock<boost::mutex> lock(up_keycode_status_param->mutex);
    up_keycode_status_param->queue->push_back(devval);
    up_keycode_status_param->cond.notify_all();     //唤醒所有的等待线程     

    log_w(" keycode=%c, keyvalue=%d, execption_info=%d\n",  keycode, keyvalue, execption_info);
}


static int get_kbdev_status(void){
    if(input_kbdev_info::s_init_idle == o_dev_status.cur_function_mode) {

        return input_kbdev_info::s_init_idle;
    }

    if(input_kbdev_enroll_paras::s_enroll_ing == o_kbdev_enroll.enroll_status){

        return input_kbdev_info::s_busy_enroll;
    }

    if(input_kbdev_auth_paras::s_auth_ing == o_kbdev_auth.auth_status){

        return input_kbdev_info::s_busy_auth;
    }

    assert(0);
    return false;
}

/** 按键综合处理， 涉及到系统模式切换、 注册验证的键值处理 等 情况 **/
static void key_input_event_listener(const char *input_name, struct input_event *event) {
 
    char tmp[2] = {0};
    tmp[0] = event->code;
    string sobj;
    sobj.append(tmp);
	cout << "key_input_event_listener  keycode :[ "  <<  sobj  << " ]" << endl;
    //cout << "key_input_event_listener" << event->code << "  " << event->value << endl;

    unsigned int execption_info = input_no_ececption;

    #if 0
        if(event->code == Key_Code_ChangeMode)
            event->code =  Key_Code_Cancel;  // 模拟，验证手动取消功能
    #endif
    

    if(Key_Code_OK == event->code){
        
        // 按下OK按键则通知对应事件处理
        if(input_kbdev_info::s_busy_enroll == get_kbdev_status()){

            /***********注册的时候按下OK键，做了密码长度过短的判断，
             *而密码长度过长检测是动态实时检测的，动态实时检测相关代码在下面实现********/

            /***********密码长度不过短*************/
            if(o_dev_status.keys_pressed_count >= CONTENR_MIN_LENGTH){

                /**********唤醒 注册处理 下半部***********/
                eventer_enroll_with_cacel.wake_resource(); 

            }else{ /***********密码长度过短*************/
                execption_info = combine_execption_info(input_execption_operation_irregular,   \
                                                              detail_operation_kb_keys_pressed_tooshort);
                // 这里可以通知上层，语音播报“您输入的密码长度不合格” 并自动重启一次密码注册过程。
                log_e("input_execption_operation_irregular....execption_info = 0x%x \n", execption_info);
                inmanager_do_cancel_func(execption_info);
            }
        }

        /**********  auth(验证)时: 不进行密码长短检测，因为没有必要提示用户密码过长还是过短。
         *               直接比对，返回结果是验证成功还是错误 **********/
        if(input_kbdev_info::s_busy_auth == get_kbdev_status()){

            /**********唤醒 验证处理 下半部***********/
            eventer_auth_with_cacel.wake_resource();
        }   

        // get_user_id    

    }else if((event->code != Key_Code_ChangeMode)&&(event->code != Key_Code_Cancel)){
        /*** 数据键0-9处理
         * 
         * 按键板硬件说明：我的按键板上由数据键(数字0-9)和两个功能键(一个C键、一个OK键)组成。 并没有其他的功能键。
         *          一般的按键板的数据键由数字键和一些字母键构成。我的按键板上的数据键也只有数字0-9, 没有英文字母键。
         * ****/

        int cur_validfunc = get_kbdev_status();

        if((input_kbdev_info::s_busy_enroll == cur_validfunc) || (input_kbdev_info::s_busy_auth == cur_validfunc))  {

            /************密码长度如实记录**************/
            o_dev_status.keys_pressed_count++; 

            /*******只记录有效长度的密码：如果用户按下100位密码，我也只最多记录12位，同时结合记录下的密码长度keys_pressed_count进行判断*****/
            if(o_dev_status.keys_pressed_count < CONTENR_MAX_LENGTH){
                
                if( (Key_Code_0 <= event->code) && (event->code <= Key_Code_9) ){
                    /********* 数据键值本地存储 **********/
                    o_dev_status.keysval_content[o_dev_status.keys_pressed_count] =  event->code; 

                }
            }else if((o_dev_status.keys_pressed_count >= CONTENR_MAX_LENGTH) && (input_kbdev_info::s_busy_enroll == cur_validfunc)){
            /**** 注册时做一个密码长度的实时检测,
              **  验证时不做该检测，这样可以防止让验证的人通过反复实验来摸清楚密码长度范围这个底细 *****/

                /*** 注册状态下检测到用户输入的按键数量超过了最大数目，也就是超过了最大的密码长度
                 此时应该向上层发送该消息，通知上层应用调用取消注册接口，
                 那为什么不直接在本层代码内取消注册呢？ 虽然一个消息向上传，最后又下发到本层，绕了一圈，但是这样更加灵活，
                 我们可以在向上传递的各层代码内去做另外的事情，例如可以在上层的某层框架内去调用输出的语音设备用来提示用户：您输入的密码超过了最大长度，注册失败！
                 很明显，本CPP源文件专职处理按键设备的逻辑，这是输入设备，而语音设备是输出设备，由不同的代码框架进行管理。
                 所以向上传递消息，可以在多层代码框架间游走。 也是为了更好地把决策权交给上层应用逻辑，以便拓展，更方便地实现更丰富的功能 ****/
                execption_info = combine_execption_info(input_execption_operation_irregular, detail_operation_kb_keys_pressed_toolong);
   
                /*** 这里可以通知上层，语音播报“您输入的密码长度不合格”, 并自动重启一次密码注册过程 ***/
                log_e("input_kb_keyspressed_toolong.... \n");
                inmanager_do_cancel_func(execption_info);
            }
        }
        
    }else if(Key_Code_ChangeMode == event->code){ 
        /********* 模式切换键 上传处理***********/
        unsigned char execption_info = input_no_ececption;
        keys_report_handler(event->code, event->value, execption_info);


    }else{
        /**** 当前功能取消键 处理  ************/

        //当前硬件，没有多余的按键来支持该功能，所以我在这里加入断言。如果以后需要开启此功能，屏蔽这里的断言即可。
        log_e("Key_Code_Cancel: 当前硬件，没有多余的按键来支持该功能 \n");
        assert(0);   
        //execption_info = combine_execption_info(input_no_ececption, detail_manual_cancel);  
        //inmanager_do_cancel_func();
    }
      
    /** 备注：
     *  OK键的键值是不需要上传给上层应用的，OK键负责触发本地的功能立即执行，且功能执行的结果会立即反馈给上层应用，所以我们的OK键的键值无需再传给上层应用，
        我们有一个消息发送方就够了，不建议搞多个消息发送方。
        我们也可以将OK键上传，然后由上层应用层层向下调用到本地的func_XX_part2操作(例如验证时，用户密码按完毕以后，后续需要进行核对密码的操作)，
        显然，这把代码复杂化了。
        最终，我们选择本地线程作为该消息发送方(即负责核对密码的线程，在执行完毕密码核对后，会主动上报结果，以反馈上层应用)
        由此可见，将OK键的键值上传是多余的操作。
        我将此称之为：代码框架内的业务逻辑的就近处理原则。
        多层框架内的某层代码，匹配对应了一部分的业务逻辑，对于新的需求点，只要在其匹配的业务逻辑范围内，应该按照就近原则处理  
    *************/
    
}

key_inputdev::~key_inputdev() { 

    pkey_inputdev_instance = NULL;
    cout << "~key_inputdev()" << endl;
}

key_inputdev* key_inputdev::pkey_inputdev_instance = NULL;

key_inputdev::key_inputdev() {    

    // 向APP驱动层注册回调
    input_manager_drv_register_event_listener(key_inputdev_type,  key_input_event_listener);

    // 开启本设备的各个功能线程: 注册、验证、删除 等，以封装功能基石，以及该过程所需的一些资源的初始化
    //先列出线程
    //boost::thread thread_enroll(thread_enroll_run);
    //thread_enroll.detach();

    boost::unique_lock<boost::mutex> lock(local_mutex);
    //再列出线程工作所必须的一些资源的初始化
    o_dev_status.cur_function_mode = input_kbdev_info::s_init_idle; 
    o_dev_status.protect = NULL;


    eventer_enroll_with_cacel.event_waiter_register_func_part_up(func_enroll_part1,      NULL);
    eventer_enroll_with_cacel.event_waiter_register_func_part_down(func_enroll_part2,    NULL);
    eventer_enroll_with_cacel.event_waiter_register_cancel_funcpartdown(func_enroll_cancelpart2, NULL);
    eventer_enroll_with_cacel.create_event_loop();


    eventer_auth_with_cacel.event_waiter_register_func_part_up(func_auth_part1,      NULL);
    eventer_auth_with_cacel.event_waiter_register_func_part_down(func_auth_part2,    NULL);
    eventer_auth_with_cacel.event_waiter_register_cancel_funcpartdown(func_auth_cancelpart2, NULL);
    eventer_auth_with_cacel.create_event_loop();

}


key_inputdev* key_inputdev::pkey_inputdev_construct_instance(){

    boost::unique_lock<boost::mutex> lock(mutex_singleton);
    if(pkey_inputdev_instance == NULL)  {

        std::cout << "Create: key_inputdev " <<  std::endl;
        pkey_inputdev_instance = new key_inputdev;
    }
    return pkey_inputdev_instance;
}


input_kbdev_info::input_kbdev_info():keys_pressed_count(0) {

    memset(o_dev_status.keysval_content, 0, sizeof(o_dev_status.keysval_content));
}


// 此处还包含向上层框架的消息队列发送一个消息。例如request一个语音资源。
static void execption_deal(int execption){

    //标识消息队列的发送方ID： key_inputdev_type ( "keyboard-inputdev" )

    //标识该消息的紧要程度 : 标识为异常的消息会头插入队列，并且会打算正在进行的该条语音播报。
}


/******************* 按键设备类 注册功能 业务逻辑 begin*************************/

input_kbdev_enroll_paras::input_kbdev_enroll_paras():enroll_status(input_kbdev_enroll_paras::s_enroll_not),first_password_len(0){

    o_kbdev_enroll.enroll_step = input_kbdev_enroll_paras::s_enroll_step1;
}

static void key_enroll_result_process(const unsigned char* password, int key_len, int* presult, int* detail) {

    if( input_kbdev_enroll_paras::s_enroll_step2 == o_kbdev_enroll.enroll_step ){

        if((key_len == o_kbdev_enroll.first_password_len) && (key_len!=0)){

            int success = 0;
            if(success ==  memcmp(password, o_kbdev_enroll.first_password, key_len)){
                
                *presult = e_kb_enroll_success;
                *detail = e_inputdev_results_no_detail;
            }else{

                 *presult = e_kb_enroll_fail;
                 *detail = e_kb_enroll_fail_pw_content_differ;
            }

        }else{

            *presult = e_kb_enroll_fail;
            *detail = e_kb_enroll_fail_pw_len_differ;
        }
    }
}

void func_enroll_part1(event_waiter_para*p) {

    log_w("func_enroll_part1()! \n");
    input_dev_param* para = reinterpret_cast<input_dev_param*>(p);

    if(input_kbdev_info::s_init_idle == o_dev_status.cur_function_mode){

        p_para_func_enroll_part2 = para;

        //按键设备当前正在忙碌，且处于注册模式
        o_dev_status.cur_function_mode = input_kbdev_info::s_busy_enroll;

        //标识出当前的注册状态： 注册功能已开启
        o_kbdev_enroll.enroll_status   = input_kbdev_enroll_paras::s_enroll_ing;


    }else{

        log_w("it has been under enrolling mode already! \n");
    }

}

void func_enroll_part2(event_waiter_para*p) {

    input_dev_param* p_para = reinterpret_cast<input_dev_param*>(p);
    int result = 0, detail = 0, isdone = 0;


    if(p_para != NULL){

        log_d("实时传入的参数 status :%d \n", p_para->status);
    }

    log_w("o_kbdev_enroll.enroll_step = %d \n",o_kbdev_enroll.enroll_step);

    if(input_kbdev_enroll_paras::s_enroll_step1 == o_kbdev_enroll.enroll_step){

            // 判断第一次注册的键值是否有效
            // 例如，可以做一些键值筛选(例如是否包含一些特殊的非法字符)， 
            //      和密码复杂度的检测(例如，遇到全部键值都相同的密码就提示：安全系数低)

        #if 0
            if(o_dev_status.keys_pressed_count < CONTENR_MIN_LENGTH){

                /*  I have been prevent this from happening, and now the process is unnecessary. <google translate>
                result = e_kb_enroll_fail;
                detail = ;
                isdone = curfuncdone;
                */
                log_w("now the process is unnecessary, It seems that your thinking is still not precise enough\n");

            }
        #endif   

        assert(o_dev_status.keys_pressed_count >= CONTENR_MIN_LENGTH);

        // 记录第一次注册的有效键值
        memset(o_kbdev_enroll.first_password, 0, sizeof(o_kbdev_enroll.first_password));
        memcpy(o_kbdev_enroll.first_password,  o_dev_status.keysval_content, o_dev_status.keys_pressed_count);

        o_kbdev_enroll.first_password_len = o_dev_status.keys_pressed_count;

        log_d("first_password : %s", o_kbdev_enroll.first_password);


        o_kbdev_enroll.enroll_step = input_kbdev_enroll_paras::s_enroll_step2;

        isdone = curfuncnotdone;
    
    } else{  
            /****** 如果是第2次注册，则需要进行两次的密码比对、将注册结果通知给上层应用等操作 *********/
            key_enroll_result_process(o_dev_status.keysval_content, o_dev_status.keys_pressed_count, \
                                                                              &result, &detail);

            if(e_kb_enroll_success == result){
                memset(p_para->content, 0, sizeof(p_para->content));

                //将注册结果通知给上层应用
                memcpy(p_para->content, o_dev_status.keysval_content, o_dev_status.keys_pressed_count); 
            }

            /**** 清理现场*********/
            o_kbdev_enroll.enroll_status = input_kbdev_enroll_paras::s_enroll_not; 
            o_kbdev_enroll.enroll_step  = input_kbdev_enroll_paras::s_enroll_step1;
            o_kbdev_enroll.first_password_len = 0;

            memset(o_dev_status.keysval_content, 0, sizeof(o_dev_status.keysval_content));

            o_dev_status.keys_pressed_count = 0;

            isdone = curfuncdone;
    }

    o_dev_status.cur_function_mode = input_kbdev_info::s_init_idle;


    // 复位公有(注册、验证 等功能通用)键值容器、按键计数器
    memset(o_dev_status.keysval_content, 0, sizeof(o_dev_status.keysval_content));
    o_dev_status.keys_pressed_count = 0; 


    // 结束后，反馈注册发起者
    boost::unique_lock<boost::mutex> lock(p_para->mutex);

    p_para->status = result;
    p_para->detail = detail;
    p_para->isfuncdone = isdone;

    p_para->cond.notify_all();
    
    log_v("enroll  status : %d", result);
    log_v("enroll  detail : %d", detail);
    log_v("enroll  isdone : %d", isdone);
}


void func_enroll_cancelpart2(event_waiter_para*p) {

    int execption_info =  reinterpret_cast<int>(p);
    log_d("func_enroll_cancelpart2 : %d \n",  execption_info);

    if(input_kbdev_info::s_init_idle != o_dev_status.cur_function_mode){

        log_d("func_enroll_cancelpart2 is doing. LMW\n"); 

        /**** 清理现场*********/
        o_kbdev_enroll.enroll_status = input_kbdev_enroll_paras::s_enroll_not;
        o_kbdev_enroll.enroll_step   = input_kbdev_enroll_paras::s_enroll_step1;
        o_kbdev_enroll.first_password_len = 0;

        o_dev_status.cur_function_mode = input_kbdev_info::s_init_idle;

        // 复位公有(注册、验证 等功能通用)键值容器、按键计数器
        memset(o_dev_status.keysval_content, 0, sizeof(o_dev_status.keysval_content));
        o_dev_status.keys_pressed_count = 0; 

        if(input_execption_operation_irregular == execption_info){

            log_w("ALSA says: input_execption_operation_irregular \n");

        }else if(input_execption_timeout == execption_info){

            log_w("ALSA says: input_execption_timeout \n");
        }

        // 取消注册后，反馈注册者
        boost::unique_lock<boost::mutex> lock(p_para_func_enroll_part2->mutex);

        p_para_func_enroll_part2->status = e_kb_enroll_fail;

        log_w("cancel: status = %d \n", p_para_func_enroll_part2->status);

        p_para_func_enroll_part2->execption_id  = get_execption_id_from_info(execption_info); 
        p_para_func_enroll_part2->cancel_reason = get_execption_detail_from_info(execption_info); 

        p_para_func_enroll_part2->isfuncdone = curfuncdone;
        p_para_func_enroll_part2->cond.notify_all();

        p_para_func_enroll_part2 = NULL;

    }else{

        log_w("it has been  canceled already! \n"); 
        log_w("这里还可以添加语音播报，请勿重复取消! UTG\n"); 
        
    }
}
/******************* 按键设备类 注册功能 业务逻辑 end***********************/




/******************* 按键设备类 验证功能 业务逻辑 begin*********************/

input_kbdev_auth_paras::input_kbdev_auth_paras():auth_status(s_auth_not){

    memset(o_dev_status.keysval_content, 0, sizeof(o_dev_status.keysval_content));
}



void func_auth_part1(event_waiter_para*p) {

    input_dev_param* para = reinterpret_cast<input_dev_param*>(p);

    if(input_kbdev_info::s_init_idle == o_dev_status.cur_function_mode){

        log_w("func_auth_part1() begins... \n");

        p_para_func_auth_part2 = para;

        //按键设备当前正在忙碌，且处于验证模式
        o_dev_status.cur_function_mode = input_kbdev_info::s_busy_auth;

        //标识出当前的验证状态： 验证功能已开启
        o_kbdev_auth.auth_status   = input_kbdev_auth_paras::s_auth_ing;

    }else{

        log_w("it has been under authing mode already! \n");
    }

}

void func_auth_part2(event_waiter_para*p) {

    int result = 0, detail = 0, isdone = 0;

    input_dev_param* p_para = reinterpret_cast<input_dev_param*>(p);


    memset(o_kbdev_auth.auth_password, 0, sizeof(o_kbdev_auth.auth_password));

    memcpy(o_kbdev_auth.auth_password,  o_dev_status.keysval_content, o_dev_status.keys_pressed_count);
    o_kbdev_auth.auth_password_len    = o_dev_status.keys_pressed_count;

    log_w("auth_password done: [ %s ]", o_kbdev_auth.auth_password);

    //key_auth_result_process(o_kbdev_auth.auth_password, o_kbdev_auth.auth_password_len, char* PW_Dir);
             

    // 清理现场 -------------------------------------------------
    o_kbdev_auth.auth_status = input_kbdev_auth_paras::s_auth_not;
    o_kbdev_auth.auth_password_len = 0;

    o_dev_status.cur_function_mode = input_kbdev_info::s_init_idle;

    // 复位公有(注册、验证 等功能通用)键值容器、按键计数器
    memset(o_dev_status.keysval_content, 0, sizeof(o_dev_status.keysval_content));
    o_dev_status.keys_pressed_count = 0; 



    // 结束后，反馈验证发起者
    boost::unique_lock<boost::mutex> lock(p_para->mutex);

    result= 99; // e_kb_auth_fail;

    p_para->status = result;
    p_para->detail = detail;
    p_para->isfuncdone = isdone;

    p_para->cond.notify_all();

}


void func_auth_cancelpart2(event_waiter_para*p) {

    int execption_info =  reinterpret_cast<int>(p);
    log_d("execption_info (auth_cancelpart2): %d \n",  execption_info);

    if(input_kbdev_info::s_init_idle != o_dev_status.cur_function_mode){

        log_d("func_auth_cancelpart2 is doing. \n"); 

        // 清理现场 ------------------------------------------------------
        o_kbdev_auth.auth_status = input_kbdev_auth_paras::s_auth_not;
        o_kbdev_auth.auth_password_len = 0;

        o_dev_status.cur_function_mode = input_kbdev_info::s_init_idle;

        // 复位公有(注册、验证 等功能通用)键值容器、按键计数器
        memset(o_dev_status.keysval_content, 0, sizeof(o_dev_status.keysval_content));
        o_dev_status.keys_pressed_count = 0; 

        // 结束后，反馈验证发起者
        boost::unique_lock<boost::mutex> lock(p_para_func_auth_part2->mutex);

        p_para_func_auth_part2->status = e_kb_auth_fail;
        p_para_func_auth_part2->cancel_reason = get_execption_detail_from_info(execption_info); 
        p_para_func_auth_part2->execption_id  = get_execption_id_from_info(execption_info); 

        p_para_func_auth_part2->cond.notify_all();

        p_para_func_auth_part2 = NULL;

    }else{

        log_w("it has been  canceled already! \n"); 
        log_w("这里还可以添加语音播报，请勿重复取消! UTF-8\n"); 
        
    } 
}


/******************* 按键设备类 验证功能 业务逻辑 end***********************/


/******************* 按键设备类 获取USRID功能 业务逻辑 begin****************/



/******************* 按键设备类 获取USRID功能 业务逻辑 end*****************/




/******************* 按键设备类 接口实现 *****************************/
int key_inputdev::suspend(void){


}

int key_inputdev::resume(void){

}

int key_inputdev::enroll(input_dev_param *param){

    if( input_kbdev_info::s_init_idle == o_dev_status.cur_function_mode ){

        eventer_enroll_with_cacel.wake_event(reinterpret_cast<int>(param));

    }else{

        log_w("key_inputdev::enroll is Busy! \n");
    }
}

int key_inputdev::cancel_enroll(input_dev_param *param){

    if((input_kbdev_info::s_busy_enroll == o_dev_status.cur_function_mode)&&  \
               (input_kbdev_enroll_paras::s_enroll_ing == o_kbdev_enroll.enroll_status) ){

        eventer_enroll_with_cacel.cancel_funcpartdown(reinterpret_cast<int>(param)); 

    }else{

        log_w("智能语音提醒：已经取消了，别再按取消按键了，省点电吧！ \n"); // GB2312
    }
         
}

int key_inputdev::authenticate( input_dev_param *param){
    if( input_kbdev_info::s_init_idle == o_dev_status.cur_function_mode ){

        eventer_auth_with_cacel.wake_event(reinterpret_cast<int>(param));

    }else{

        log_w("key_inputdev::auth is Busy! \n");
    }
}

int key_inputdev::cancel_authenticate( input_dev_param *param){

    if((input_kbdev_info::s_busy_auth == o_dev_status.cur_function_mode)&&  \
               (input_kbdev_auth_paras::s_auth_ing == o_kbdev_auth.auth_status) ){

        eventer_auth_with_cacel.cancel_funcpartdown(reinterpret_cast<int>(param)); 

    }else{

        log_w("智能语音提醒：已经取消了，别再按取消按键了，省点电吧！ \n"); 
    }
}

int key_inputdev::delete_user( input_dev_param *param){


}

int key_inputdev::cancel_delete_user( input_dev_param *param){


}

int key_inputdev::get_userid( input_dev_param *param){


}

int key_inputdev::cancel_get_userid( input_dev_param *param){


}


/**设备处于阻塞态，等待外部唤醒，那么通过调用此接口即可唤醒之
 * 
 * 假设有多个资源等待被唤醒，针对这种场景，我的思路是通过字符串作为中间媒介来标识该唤醒哪个线程。
 * 所以外部传入的信息内只要有正确的字符串，后续能够匹配上就行了。
 * 
 * 所以，我可以编写一个字符串形式的通信类，每次建立新的通信信道，依赖于new一个新的信号量的方法，传入字符串参数，然后绑定并记录到该类的管理器。
 *       同理，还有删除通信信道的接口，销毁信号量，同时销毁与之绑定的字符串信息。 
 *       关于绑定信息，可以使用链表或数组来实现。
 * **/
int key_inputdev::notify_resource_to_inputdev( input_dev_param *param){


}

int key_inputdev::notify_param_handle( input_dev_param *param){

    if (up_keycode_status_param == NULL) {
        up_keycode_status_param = param;

        log_d("notify_param_handle param = %d \n", param);
    }

    return 0;
}
/****************** 按键设备类 接口实现 **********************/


// 设备层，观察设备驱动层。 但是这里不需要使用观察者模式。
// 因为设备层和某个设备驱动层，是一对一的关系，不会出现多个观察者。
// 所以，没有很大必要去使用观察者模式。
// 采集基于注册-回调的简单方式就可以满足需求。
